package com.tamartech.greendb.canvass;

import java.text.SimpleDateFormat;
import java.util.List;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.tamartech.greendb.data.Address;
import com.tamartech.greendb.data.Contact;
import com.tamartech.greendb.data.ElectoralRollEntry;
import com.tamartech.greendb.data.Person;
import com.tamartech.greendb.data.VotingInfo;
import com.tamartech.greendb.util.GreendbUtils;

public class CanvassSheetWriter
{
    private List<ElectoralRollEntry> entries; 
    private Document document;
    
    private final static float[] TABLE_COL_WIDTHS = new float[] {0.1F, 0.05F, 0.05F, 0.6F, 0.2F};

    private PdfPTable tablePrototype;
 
    private Font headingFont = new Font(Font.FontFamily.HELVETICA, 14.0F, Font.BOLD);
    private Font bodyFont = new Font(Font.FontFamily.HELVETICA, 11.0F);
    
    private SimpleDateFormat dateFormat = new SimpleDateFormat ("d MMM yyyy");
    
    public CanvassSheetWriter (List<ElectoralRollEntry> entries, Document document)
    {
        this.entries = entries;
        this.document = document;
        
        tablePrototype = new PdfPTable (TABLE_COL_WIDTHS);
        tablePrototype.setWidthPercentage(100.0F);
        tablePrototype.getDefaultCell().setBorder(0);
        tablePrototype.getDefaultCell().setPaddingBottom(5.0F);
        tablePrototype.setKeepTogether(true);
    }
    
    public void write() throws Exception
    {
        for (ElectoralRollEntry e : entries)
        {
            document.add(canvassEntry (e));
        }
    }    
    
    private PdfPTable canvassEntry (ElectoralRollEntry e)
    {
        PdfPTable table = createTable();

        PdfPCell headerCell = new PdfPCell(heading(e.getAddress()));
        headerCell.setColspan(5);
        headerCell.setHorizontalAlignment (Element.ALIGN_CENTER);
        table.addCell(headerCell);
        
        PdfPCell personCell = new PdfPCell(person(e.getPerson()));
        personCell.setColspan(4);
        table.addCell(personCell);
        
        PdfPCell votedCell = new PdfPCell(voted(e.getPerson()));
        table.addCell(votedCell);
        
        Contact c = e.getPerson().getLastContact();
        
        if (c != null)
        {
            PdfPCell contactDateCell = new PdfPCell(contactDate(c));
            table.addCell(contactDateCell);
        
            PdfPCell contactRankCell = new PdfPCell(contactRank(c));
            table.addCell(contactRankCell);
        
            PdfPCell contactPartyCell = new PdfPCell(contactParty(c));
            table.addCell(contactPartyCell);
        
            PdfPCell contactNotesCell = new PdfPCell(contactNotes(c));
            contactNotesCell.setColspan(2);
            table.addCell(contactNotesCell);
        }

        PdfPCell notesCell = new PdfPCell(notesField());
        notesCell.setColspan(5);
        notesCell.setFixedHeight(25);
        table.addCell(notesCell);
        
        return table;
    }
    
    private PdfPTable createTable()
    {
        return new PdfPTable(tablePrototype);
    }

    private Phrase heading (Address a)
    {
        return new Phrase (a.getAddress1() + ", " + a.getAddress2(), headingFont);
    }

    private Phrase person (Person p)
    {
        Phrase phrase = new Phrase();
        
        phrase.add (new Chunk (p.getSurname() + ", " + p.getFirstNames(), new Font (bodyFont.getFamily(), bodyFont.getSize(), Font.BOLD)));

        if (GreendbUtils.isNewPerson(p))
            phrase.add(new Chunk (" **NEW: " + dateFormat.format (p.getFirstSeenRoll().getDate()) + "**"));
        
        if (p.getBirthday18() != null)
            phrase.add(new Chunk (" (18th: " + dateFormat.format (p.getFirstSeenRoll().getDate()) + ")"));
            
        return phrase;
    }
    
    private Phrase voted (Person p)
    {
        Phrase phrase = new Phrase();
       
        VotingInfo vi = p.getLastVoted();
        
        if (vi != null)
        {
            phrase.add(new Chunk ("Last voted: " + dateFormat.format (vi.getElection().getDate()) + " (" + vi.getElection().getType() + ")"));
        }
        return phrase;
    }

    private Phrase contactDate (Contact c)
    {
        return new Phrase (dateFormat.format (c.getDate()));
    }

    private Phrase contactRank (Contact c)
    {
        String rank = (c.getRank() == null ? "-" : c.getRank().toString());
        return new Phrase (rank);
    }

    private Phrase contactParty (Contact c)
    {
        String party = (c.getParty() == null ? "-" : c.getParty());
        return new Phrase (party);
    }

    private Phrase contactNotes (Contact c)
    {
        return new Phrase (c.getNotes());
    }

    private Phrase notesField ()
    {
        return new Phrase ("Notes");
    }

    
}
